package org.water.base.service;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.water.base.entity.AbstractEntity;
import org.water.base.repository.BaseRepository;



public abstract class BaseService<T extends AbstractEntity<?>, ID extends Serializable> {

	//日志
	protected static Logger logger=LogManager.getLogger(BaseService.class);
	
	public BaseService() {
		
	}
	/**
	 * 基础dao
	 */
	protected BaseRepository<T, ID> baseRespository;
	
	@Autowired
    public void setBaseRepository(BaseRepository<T, ID> baseRespository) {
        this.baseRespository = baseRespository;
    }
	/**
	 * 保存
	 * @param t
	 */
	public void save(T t)
	{
		baseRespository.save(t);
		logger.info("save "+t.toString());
	}
	/**
	 * 保存多条数据
	 * @param ts
	 */
	public void save(List<T> ts)
	{
		baseRespository.saveAll(ts);
		if(!ts.isEmpty()) logger.info("save "+String.valueOf(ts.get(0).getClass().toString())+"  count:"+ts.size());
		//logger.info("save "+ts.toString()+"  count:"+ts.size()); //数据量大时打出日志太多，直接打出数据量
	}
	/**
	 * 更新  空字段不进行更新
	 * @param t
	 * @throws IllegalAccessException 
	 * @throws IllegalArgumentException 
	 * @throws NoSuchFieldException 
	 * @throws SecurityException 
	 */
	public void update(T t)
	{
		@SuppressWarnings("unchecked")
		T temp=findOne((ID)t.getId());
		if(temp!=null)
		{
			try{
				Field[] declaredFields = t.getClass().getDeclaredFields(); 
				for (Field field : declaredFields) {    
		            field.setAccessible(true);  
		            Object value=field.get(t);
		            if(value!=null && !Modifier.isStatic(field.getModifiers()) && !Modifier.isFinal(field.getModifiers())) //排除static 或者 final的属性
		            {
		            	/**PropertyDescriptor pd = new PropertyDescriptor(field.getName(), temp.getClass()); 
		            	Method method = pd.getWriteMethod();
		            	if(method!=null)
		            	{
		            		method.invoke(temp, value);
		            	}**/
		            	Field tf=temp.getClass().getDeclaredField(field.getName());
		            	if(tf!=null)
		            	{
		            		tf.setAccessible(true);
		            		tf.set(temp, value);
		            	}
		            }
		        } 
				save(temp);
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
		}
		else
		{
			save(t);
		}
	}
	/**
	 * 根据 主键查询一条数据
	 * @param id
	 * @return
	 */
	public T findOne(ID id)
	{
		return baseRespository.findById(id).get();
	}
	/**
	 * 查询所有数据
	 * @return
	 */
	public List<T> findAall()
	{
		return baseRespository.findAll();
	}
	/**
	 * 根据id查询多个数据
	 * @param ids
	 * @return
	 */
	public List<T> findAll(ArrayList<ID> ids)
	{
		return baseRespository.findAllById(ids);
	}
	/**
	 * 根据主键删除数据
	 * @param id
	 */
	public void del(ID id)
	{
		baseRespository.delete(id);
	}
	/**
	 * 获取数据总量
	 * @return
	 */
	public Long count()
	{
		return baseRespository.count();
	}
}
